<?php

namespace App\Ad\Docking;

use App\Ad\MediaApi\MediaApiBase;
use App\Commons\CommonConstant;
use App\Datalog\AdMonitorLog;
use App\Models\AdMonitor;
use App\Models\AdPlan;
use App\Models\FirstupAd;
use App\Models\Firstups;
use App\Models\Log\LogAdMonitor;
use App\Models\Log\LogAdMonitorInfo;
use App\Models\Log\LogAdPostbackMedia;
use Illuminate\Http\Request;

// 百度应用-信息流
// https://dev2.baidu.com/content?sceneType=0&pageId=101213&nodeId=663&subhead=
class BaiduAppXxl extends DockingBase
{
    // 点击监控参数
    protected $monitorParams = [
        'userid'         => '__USER_ID__',        // 账户ID
        'aid'            => '__IDEA_ID__',        // 创意ID
        'pid'            => '__PLAN_ID__',        // 计划ID
        'uid'            => '__UNIT_ID__',        // 单元ID
        'callback_url'   => '__CALLBACK_URL__',   // 效果数据回传URL
        'click_id'       => '__CLICK_ID__',       // 点击或曝光唯一标识
        'imei_md5'       => '__IMEI__',           // Android设备标识
        'oaid'           => '__OAID__',           // Android Q 及更高版本的设备号
        'oaid_md5'       => '__OAID_MD5__',       // Android Q 及更高版本的设备号
        'android_id_md5' => '__ANDROIDID__',      // 安卓id
        'mac'            => '__MAC__',            // mac地址
        'mac_md5'        => '__MAC1__',           // mac地址
        'ip'             => '__IP__',             // ip
        'ua'             => '__UA__',             // user agent
        'os_version'     => '__OS__',             // 从UA中解析出来系统版本 IOS样例： 14.4.2；Android样例 8.1.0；
        'ts'             => '__TS__',             // 时间戳，单位：毫秒(ms)
        'device_info'    => '__DEVICE_INFO__',    // 设备信息,IOS样例：iPhone13,4 Android样例：EVA-AL10
        'sign'           => '__SIGN__',           // sign
        'os_type'        => '__OS_TYPE__',        // 操作系统类型 安卓：2；iOS：1；
        'model'          => '__MODEL__',           // 客户端获取的原始设备信息数据
    ];
    protected $monitorParamsIos = [
        'userid'         => '__USER_ID__',        // 账户ID
        'aid'            => '__IDEA_ID__',        // 创意ID
        'pid'            => '__PLAN_ID__',        // 计划ID
        'uid'            => '__UNIT_ID__',        // 单元ID
        'callback_url'   => '__CALLBACK_URL__',   // 效果数据回传URL
        'click_id'       => '__CLICK_ID__',       // 点击或曝光唯一标识
        'idfa'           => '__IDFA__',           // IOS设备标识
        'mac'            => '__MAC__',            // mac地址
        'mac_md5'        => '__MAC1__',           // mac地址
        'ip'             => '__IP__',             // ip
        'ua'             => '__UA__',             // user agent
        'os_type'        => '__OS_TYPE__',        // 操作系统类型 安卓：2；iOS：1；
        'ts'             => '__TS__',             // 时间戳，单位：毫秒(ms)
        'device_info'    => '__DEVICE_INFO__',    // 设备信息,IOS样例：iPhone13,4 Android样例：EVA-AL10
        'caid'           => '__CAID__',           // ios caid
        'model'          => '__MODEL__',           // 客户端获取的原始设备信息数据
    ];

    // 转化类型映射
    protected $eventTypeMap = [
        CommonConstant::EVENT_FIRSTUP => 'activate',
        CommonConstant::EVENT_REG     => 'register',
        CommonConstant::EVENT_PAY     => 'orders',
    ];

    // 此接口由子类继承
    // 获得点击监控链接拼接参数
    public function getMonitorParams($device_type): string
    {
        if ($device_type == CommonConstant::DEVICE_TYPE_IOS) {
            return http_build_query($this->monitorParamsIos);
        } else {
            return http_build_query($this->monitorParams);
        }
    }

    // 此接口由子类继承
    // 处理落地监控数据
    public function handleMonitorInfo(Request $request)
    {
        $osList = ['1' => 2, '2' => 1];

        // 待匹配日志
        $params           = $request->all();
        $log              = LogAdMonitor::suffix(date('Ym'));
        $log->create_time = time();
        $log->plan_id     = $params['plan_id'];
        $log->imei        = $params['imei'] ?? '';
        $log->idfa        = $params['idfa'] ?? '';
        $log->android_id  = $params['android_id'] ?? '';
        $log->oaid        = $params['oaid'] ?? '';
        $log->device_type = $osList[$params['os_type'] ?? 3] ?? 0;
        $log->ip          = $params['ip'] ?? '';
        $log->save();

        // 完整日志
        $info              = LogAdMonitorInfo::suffix(date('Ym'));
        $info->create_time = time();
        $info->plan_id     = $params['plan_id'];
        $info->monitor_id  = $log->id;
        $info->data        = json_encode($params, JSON_UNESCAPED_UNICODE);
        $info->save();

        // 落地日志
        AdMonitorLog::getInstance()->addLog($log, $info);

        return yqok();
    }

    // 此接口由子类继承
    // 是否可以基于ip去匹配数据
    public function needCheckUa()
    {
        return true;
    }

    /**
     * 此接口由子类继承
     * 根据媒体加密方式-生成对应的设备码，用于匹配
     * @param int      $device_type 设备类型
     * @param string[] $device_nums 设备码
     * @return array
     */
    public function getMonitorDeviceNum($device_type, $device_nums): array
    {
        $data = [];
        foreach ($device_nums as $key => $val) {
            switch ($key) {
                case 'idfa':
                    $data[$key] = $val;
                    break;
                case 'oaid':
                    $data[$key] = $val;
                    break;
                case 'imei':
                    $data[$key] = $val;
                    break;
                case 'android_id':
                    $data[$key] = $val;
                    break;
            }
        }

        return $data;
    }

    private function createSign($url, $key)
    {
        $url = preg_replace('/(&sign.*)/i', '', $url);
        return md5($url . $key);
    }

    /**
     * 此接口由子类继承
     * 将用户行为进行api上报转化，如激活注册付费
     * 文档地址：https://bytedance.feishu.cn/docx/doxcnsCqXkvxoAg36GDzkRRRuAq
     * @param int $event_type 事件类型 如激活注册付费
     * @param AdMonitor $monitor
     * @param FirstupAd $firstup_ad
     * @param mixed $mod 事件对应的模型 激活 Firstup 注册 Users 付费 Orders
     * @return int 处理结果状态
     */
    public function postbackToMedia($event_type, AdMonitor $monitor, FirstupAd $firstup_ad, $mod): int
    {
        // 此事件不需要上报
        if (!isset($this->eventTypeMap[$event_type])) {
            return LogAdPostbackMedia::STATUS_NONEED;
        }

        $plan = AdPlan::find($firstup_ad->plan_id);
        if ($plan['access_type'] != AdPlan::ACCESS_TYPE_API) {
            return LogAdPostbackMedia::STATUS_NOTAPI;
        }

        // 如果是充值转换
        $a_value = 0;
        if ($event_type == CommonConstant::EVENT_PAY) {
            $a_value = $mod->call_money*100;
        }

        $monitor_data = json_decode($monitor->data, true);
        $url = $monitor_data['callback_url'];
        $url = str_replace('{{ATYPE}}', $this->eventTypeMap[$event_type], $url);
        $url = str_replace('{{AVALUE}}', $a_value, $url);

        // 匹配类型
        $cb_join_type = 'ip';
        if ($firstup_ad->match_type == FirstupAd::MATCH_DEVICE) {
            $firstup = Firstups::find($firstup_ad->firstup_id);
            foreach (['oaid', 'imei', 'idfa', 'android_id'] as $id) {
                if (!empty($firstup[$id])) {
                    $cb_join_type = $id;
                    break;
                }
            }
        }
        $url .= "&cb_join_type={$cb_join_type}";

        $url .= '&sign=' . $this->createSign($url, $plan['extend_1']);
        $res  = MediaApiBase::getInstance()->curl($url, [], false, true);
        if ($res[0] != 200) {
            yqlog($res);
            return LogAdPostbackMedia::STATUS_FAIL;
        }

        $ret = json_decode($res[1], true);
        if ($ret['error_code'] != 0) {
            yqlog($res);
            return LogAdPostbackMedia::STATUS_FAIL;
        }

        return LogAdPostbackMedia::STATUS_SUCC;
    }

    // 此接口由子类继承
    // 匹配成功后补齐监控数据
    public function supplementMonitorInfo(FirstupAd $firstup_ad, AdMonitor $monitor)
    {
        $data = json_decode($monitor->data, true);

        foreach (['userid', 'pid', 'uid', 'aid'] as $id) {
            $value = $data[$id] ?? 0;
            if (!is_numeric($value)) {
                $data[$id] = 0;
            }
        }

        $firstup_ad->advertiser_id = $data['userid'] ?? 0;  // 广告主id
        $firstup_ad->adgroup_id    = $data['pid'] ?? 0;     // 计划id
        $firstup_ad->ad_id         = $data['uid'] ?? 0;     // 单元id
        $firstup_ad->creative_id   = $data['aid'] ?? 0;     // 创意id
    }
}
